/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * @author Sergey I. Salishev
 */
package org.apache.wikimark.http;

import java.util.Random;

/**
 * Class for creating multipart/form-data (rfc2388) POST requests 
 * The data format is MIME (rfc2046) 
 */
public class SimpleMultipartPostRequest extends AbstractPostRequest {

	private static final int ALPHANUM_CHARS = 36;
	
	/*
	 * Should be in [1..70] 
	 */
	private static final int BOUNDARY_LENGTH = 20;
	
	private static final String CRLF = "\r\n";
	private static final Random rnd = new Random();

	private final String boundary = rndBoundary(BOUNDARY_LENGTH);	
	
	private boolean closed;
	private final String dashBoundary = "--" + boundary;
	private final String delimiter = CRLF + dashBoundary;
	private final String closeDelimiter = delimiter + "--";
	
	/**
	 * @see XFormPostRequest#XFormPostRequest(String)
	 * @param pathInfo
	 */
	public SimpleMultipartPostRequest(String pathInfo) {
		super(pathInfo);
	}

	@Override
	public void addParameter(String name, String value) {
		if (closed) {
			throw new RuntimeException("can't modify, the content is requested");
		}
		request.append(delimiter);
		appendBodyPart(name, value);
	}

	@Override
	public String getContentString() {
		if (!closed) {
			closed = true;
			request.append(closeDelimiter);
		}
		return request.toString();
	}

	@Override
	public String getContentType() {
		return "multipart/form-data; boundary=" + boundary;
	}

	private void appendBodyPart(String name, String value) {
		appendMimePartHeaders(name);
		request.append(CRLF);
		request.append(CRLF);
		request.append(value);
	}

	/*
	 * Adds "Content-Disposition" header (rfc2183) with form-data disposition
	 */
	private void appendMimePartHeaders(String name) {
		request.append(CRLF);
	    request.append("Content-Disposition: form-data;");
	    request.append(" name=\"");
	    request.append(name);
	    request.append('"');	
	}

	private String rndBoundary(int length) {
		StringBuilder res = new StringBuilder();
		while (res.length() < length) {
			long partVal = Math.abs(rnd.nextLong());
			String part = Long.toString(partVal, ALPHANUM_CHARS);
			res.append(part);
		}
	    return res.substring(0, length);
	}

}
